import { defineStore } from 'pinia'
import { ref } from 'vue'

/**
 * @typedef {Object} PPTElement
 * @property {string} id - 元素ID
 * @property {string} type - 元素类型(text/image/shape)
 * @property {Object} style - 元素样式
 * @property {any} content - 元素内容
 */

/**
 * @typedef {Object} PPTSlide
 * @property {string} id - 幻灯片ID
 * @property {string} background - 背景色或背景图
 * @property {PPTElement[]} elements - 幻灯片元素
 */

/**
 * @typedef {Object} PPTDocument
 * @property {string} id - PPT ID
 * @property {string} title - PPT标题
 * @property {string} createdAt - 创建时间
 * @property {string} updatedAt - 更新时间
 * @property {PPTSlide[]} slides - 幻灯片列表
 */
import { 
  getPPTListApi,
  getPPTDetailApi,
  createPPTApi,
  updatePPTApi,
  deletePPTApi 
} from '@/api/ppt'

export const usePPTStore = defineStore('ppt', () => {
  // 状态校验
  const validatePPTState = (state) => {
    if (!state) throw new Error('PPT state is required')
    if (!Array.isArray(state.slides)) throw new Error('Invalid slides format')
    
    // 校验幻灯片
    state.slides.forEach(slide => {
      if (!slide.id) throw new Error('Slide must have an id')
      if (!Array.isArray(slide.elements)) throw new Error('Invalid elements format')
      
      // 校验元素
      slide.elements.forEach(element => {
        if (!element.id) throw new Error('Element must have an id')
        if (!element.type) throw new Error('Element must have a type')
      })
    })
  }

  // 安全更新函数
  const safeUpdate = (updater) => {
    try {
      const prevState = JSON.parse(JSON.stringify(currentPPT.value))
      updater()
      validatePPTState(currentPPT.value)
      return true
    } catch (error) {
      console.error('State update failed:', error)
      currentPPT.value = prevState
      return false
    }
  }
  // PPT列表
  const pptList = ref([])
  // 当前编辑的PPT
  const currentPPT = ref(null)
  // 当前幻灯片索引
  const currentSlideIndex = ref(0)
  // 历史记录（用于撤销/重做）
  const history = ref([])
  // 当前历史记录位置
  const historyPosition = ref(-1)

  // 获取PPT列表
  const loadPPTList = async () => {
    try {
      const list = await getPPTListApi()
      pptList.value = list
      return list
    } catch (error) {
      console.error('获取PPT列表失败:', error)
      throw error
    }
  }

  // 初始化新PPT
  const initNewPPT = () => {
    currentPPT.value = {
      id: Date.now().toString(),
      title: '未命名演示文稿',
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
      slides: [createNewSlide()]
    }
    saveToHistory()
  }

  // 创建新幻灯片
  const createNewSlide = () => {
    return {
      id: Date.now().toString(),
      background: '#ffffff',
      elements: []
    }
  }

  // 添加幻灯片
  const addSlide = () => {
    if (!currentPPT.value) return
    
    currentPPT.value.slides.push(createNewSlide())
    currentPPT.value.updatedAt = new Date().toISOString()
    currentSlideIndex.value = currentPPT.value.slides.length - 1
    saveToHistory()
  }

  // 删除幻灯片
  const removeSlide = (index) => {
    if (!currentPPT.value || currentPPT.value.slides.length <= 1) return
    
    currentPPT.value.slides.splice(index, 1)
    currentPPT.value.updatedAt = new Date().toISOString()
    
    if (currentSlideIndex.value >= index) {
      currentSlideIndex.value = Math.max(0, currentSlideIndex.value - 1)
    }
    
    saveToHistory()
  }

  // 切换幻灯片
  const switchSlide = (index) => {
    if (!currentPPT.value || index < 0 || index >= currentPPT.value.slides.length) return
    currentSlideIndex.value = index
  }

  // 保存PPT
  const savePPT = async () => {
    try {
      if (!currentPPT.value) return
      
      currentPPT.value.updatedAt = new Date().toISOString()
      
      if (currentPPT.value.id.startsWith('temp_')) {
        // 新建PPT
        const result = await createPPTApi(currentPPT.value)
        currentPPT.value.id = result.id
      } else {
        // 更新已有PPT
        await updatePPTApi(currentPPT.value)
      }
      
      // 刷新PPT列表
      await loadPPTList()
      return true
    } catch (error) {
      console.error('保存PPT失败:', error)
      throw error
    }
  }

  // 删除PPT
  const deletePPT = async (id) => {
    try {
      await deletePPTApi(id)
      await loadPPTList()
      
      if (currentPPT.value && currentPPT.value.id === id) {
        currentPPT.value = null
      }
      
      return true
    } catch (error) {
      console.error('删除PPT失败:', error)
      throw error
    }
  }

  // 加载PPT详情
  const loadPPTDetail = async (id) => {
    try {
      const detail = await getPPTDetailApi(id)
      currentPPT.value = detail
      currentSlideIndex.value = 0
      saveToHistory()
      return detail
    } catch (error) {
      console.error('加载PPT详情失败:', error)
      throw error
    }
  }

  // 历史记录操作类型
  const HistoryActionType = {
    ADD_SLIDE: 'add_slide',
    REMOVE_SLIDE: 'remove_slide',
    UPDATE_SLIDE: 'update_slide',
    UPDATE_ELEMENT: 'update_element'
  }

  // 保存到历史记录（用于撤销/重做）
  const saveToHistory = (actionType, payload) => {
    if (!currentPPT.value) return
    
    // 只保留当前位置之后的历史记录
    history.value = history.value.slice(0, historyPosition.value + 1)
    
    // 添加操作记录
    history.value.push({
      actionType,
      payload,
      timestamp: Date.now(),
      snapshot: JSON.parse(JSON.stringify(currentPPT.value))
    })
    
    historyPosition.value = history.value.length - 1
    
    // 限制历史记录数量
    if (history.value.length > 100) {
      history.value.shift()
      historyPosition.value--
    }
  }

  // 撤销
  const undo = () => {
    if (historyPosition.value <= 0) return
    
    historyPosition.value--
    applyHistoryState(history.value[historyPosition.value])
  }

  // 重做
  const redo = () => {
    if (historyPosition.value >= history.value.length - 1) return
    
    historyPosition.value++
    applyHistoryState(history.value[historyPosition.value])
  }

  // 应用历史状态
  const applyHistoryState = (historyItem) => {
    if (!historyItem || !historyItem.snapshot) return
    
    // 使用快照恢复状态
    currentPPT.value = JSON.parse(JSON.stringify(historyItem.snapshot))
  }

  return {
    pptList,
    currentPPT,
    currentSlideIndex,
    loadPPTList,
    initNewPPT,
    createNewSlide,
    addSlide,
    removeSlide,
    switchSlide,
    savePPT,
    deletePPT,
    loadPPTDetail,
    undo,
    redo
  }
})